/*
 * Recipe.java
 *
 * Created on 18 de julio de 2007, 18:26
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package model;

import java.util.Vector;
import org.w3c.dom.Document;

/**
 *
 * @author mariano
 */
public class Recipe extends xml.Xmlizable{
    private int revision;
    private String title;
    private String description;
    private Vector<Author> authors;
    private Vector<String> tags;
    private Vector<Revision> revisions;
    private Vector<Ingredient> ingredients;
    
    /** Creates a new instance of Recipe */
    public Recipe( int revision, String title, Vector<Author> authors, Vector<String> tags, String description, Vector<Revision> revisions, Vector<Ingredient> ingredients ) {
        this.revision = revision;
        this.title = title;
        this.authors = authors;
        this.tags = tags;
        this.description = description;
        this.revisions = revisions;
        this.ingredients = ingredients;
    }

    public int getRevision() {
        return revision;
    }

    public void setRevision(int revision) {
        this.revision = revision;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Vector<Author> getAuthors() {
        return authors;
    }

    public void setAuthors(Vector<Author> authors) {
        this.authors = authors;
    }

    public Vector<String> getTags() {
        return tags;
    }

    public void setTags(Vector<String> tags) {
        this.tags = tags;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Vector<Revision> getRevisions() {
        return revisions;
    }

    public void setRevisions(Vector<Revision> revisions) {
        this.revisions = revisions;
    }

    public Vector<Ingredient> getIngredients() {
        return ingredients;
    }

    public void setIngredients(Vector<Ingredient> ingredients) {
        this.ingredients = ingredients;
    }
    
    public Index generateIndex()
    {
        int i = 1;
        Index index = new Index();
        
        for( Ingredient ingredient:ingredients )
        {
            int j = 1;
            Index subIndex = new Index();
            
            for( Step step:ingredient.getSteps() )
            {
                subIndex.addChapter( new Chapter( j, step.getTitle(), new Index() ) );
                j++;
            }
            
            index.addChapter( new Chapter( i, ingredient.getTitle(), subIndex ));
            i++;
        }
        
        return index;
    }
    
    public xml.Coleccion toXmlColeccion()
    {
        xml.Coleccion col = new xml.Coleccion( "recipe" );
        col.addNodo( "recipe-title", this.title );
        col.addNodo( "recipe-revision", "" + this.revision );
        col.addNodo( "recipe-description", this.description );
        col.addItem( this.generateIndex().toXmlColeccion() );
        
        xml.Coleccion col1 = new xml.Coleccion( "recipe-authors" );
        
        for( Author author:authors )
        {
            col1.addItem( author.toXmlColeccion() );
        }
        
        xml.Coleccion col2 = new xml.Coleccion( "recipe-revisions" );
        
        for( Revision revision:revisions )
        {
            col2.addItem( revision.toXmlColeccion() );
        }
        
        xml.Coleccion col3 = new xml.Coleccion( "recipe-tags" );
        
        for( String tag:tags )
        {
            col3.addNodo( "recipe-tag", tag );
        }
        
        xml.Coleccion col4 = new xml.Coleccion( "recipe-ingredients" );
        
        for( Ingredient ingredient:ingredients )
        {
            col4.addItem( ingredient.toXmlColeccion() );
        }
        
        col.addItem( col1 );
        col.addItem( col2 );
        col.addItem( col3 );
        col.addItem( col4 );
        
        return col;
    }
    
    public static Recipe fromXml( String str )
    {
        xml.Item col = xml.Item.fromXml( str );
        return parse( col );
    }
    
    public static Recipe fromXml( Document doc )
    {
        xml.Item col = xml.Item.fromXml( doc.getFirstChild() );
        return parse( col );
    }
    
    private static Recipe parse( xml.Item col )
    {
        if( !col.isColeccion() || col.getName() != "recipe" )
            return null;
        
        Vector<Author> vAuthors = new Vector<Author>();
        Vector<Revision> vRevisions = new Vector<Revision>();
        Vector<String> vTags = new Vector<String>();
        Vector<Ingredient> vIngredients = new Vector<Ingredient>();
        
        Index index;
        int revisionNumber = 1;
        
        xml.Coleccion c = (xml.Coleccion)col;
        
        xml.Nodo nTitle = c.getNodo( 0, "recipe-title" );
        xml.Nodo nRevision = c.getNodo( 1, "recipe-revision" );
        xml.Nodo nDescription = c.getNodo( 2, "recipe-description" );
        
        xml.Coleccion cIndex = c.getColeccion( 3, "index" );
        xml.Coleccion cAuthors = c.getColeccion( 4, "recipe-authors" );
        xml.Coleccion cRevisions = c.getColeccion( 5, "recipe-revisions" );
        xml.Coleccion cTags;
        xml.Coleccion cIngredients;
        
        if( cRevisions == null )
        {
            cTags = c.getColeccion( 5, "recipe-tags" );
            cIngredients = c.getColeccion( 6, "recipe-ingredients" );
        }
        else
        {
            cTags = c.getColeccion( 6, "recipe-tags" );
            cIngredients = c.getColeccion( 7, "recipe-ingredients" );
        }
        
        // permitimos un recipe sin revisions pero todos los otros campos
        // son obligatorios
        if( nTitle == null || nRevision == null || nDescription == null || 
            cAuthors == null || cTags == null || cIngredients == null )
            return null;
        
        if( cIndex == null )
        {
            index = new Index();
        }
        else
        {
            index = Index.fromXml( cIndex.toString() );
        }
        
        for( int i = 0 ; i < cAuthors.size() ; i++ )
        {
            xml.Coleccion authCol = cAuthors.getColeccion( i, "author" );
            
            if( authCol == null )
                continue;
            
            Author author = Author.fromXml( authCol.toString() );
            vAuthors.add( author );
        }
        
        if( cRevisions != null )
        {
            for( int i = 0 ; i < cRevisions.size() ; i++ )
            {
                xml.Coleccion revCol = cRevisions.getColeccion( i, "revision" );

                if( revCol == null )
                    continue;

                Revision revision = Revision.fromXml( revCol.toString() );
                vRevisions.add( revision );
            }
        }
        
        for( int i = 0 ; i < cTags.size() ; i++ )
        {
            xml.Nodo nTag = cTags.getNodo( i, "recipe-tag" );
            
            if( nTag == null )
                continue;
            
            vTags.add( nTag.getValue() );
        }
        
        for( int i = 0 ; i < cIngredients.size() ; i++ )
        {
            xml.Coleccion ingredientCol = cIngredients.getColeccion( i, "ingredient" );
            
            if( ingredientCol == null )
                continue;
            
            Ingredient ingredient = Ingredient.fromXml( ingredientCol.toString() );
            vIngredients.add( ingredient );
        }
        
        try
        {
            revisionNumber = Integer.parseInt( nRevision.getValue() );
        }
        catch( Exception ex ){}
        
        return new Recipe(revisionNumber,nTitle.getValue(),vAuthors,vTags,nDescription.getValue(),vRevisions,vIngredients);
    }
}
